home *** CD-ROM | disk | FTP | other *** search
- /*
- MENUBAR
- Macro to implement a simple menubar system for interacting with
- ME. You can change this so that the menu items invoke any editor
- primitive or any user-defined macro. This macro package relies
- on ME's feature of calling internal C functions in order to
- display the menubar and submenus.
-
- The menubar definiton should be in a file with an .MNU extension.
- In this macro, the CTRL-B key is used to bring up the menubar; you
- can change this key by altering the assign_key() call in the init()
- function here.
-
- The menubar definition must be in the following format :
-
- [optional comment lines]
- .....
- MENUBAR menu-name [COLOR color]
- {
- text-of-menubar-item-1
- [MENU
- {
- subpopup1-text [->function-to-call]
- ......
- }]
- }
-
- Please note that items enclosed by square brackets are optional. In this
- case, the subpopup definition after a menubar item is optional. Also,
- the function to invoke after an item is chosed is optional. Look at the
- accompanying file MENUBAR.MNU for an actual menubar definition. The
- menubar definition starts with first line with the word MENUBAR starting
- at column 1.
-
- (C) Copyright 1988 Marc Adler/Magma Systems All Rights Reserved
- */
-
- #define HORIZ 1
- #define VERT 2
- #define TOP_LEFT 3
- #define TOP_RIGHT 4
- #define BOT_LEFT 5
- #define BOT_RIGHT 6
-
- #define DOWN 208
- #define UP 200
- #define LEFT 203
- #define RIGHT 205
-
- #define MAXMENUBARITEMS 16
-
- string BoxChars[10];
-
- int MenuRow1, MenuCol1, MenuRow2, MenuCol2;
- int MenuColor;
- string MenuName;
- int MenubarBuf;
- int MenubarItemBufID;
-
- int debug;
- int MenubarWindow;
- int MenuBuf[MAXMENUBARITEMS];
- string MenuNames[MAXMENUBARITEMS];
- int PopupWindow[MAXMENUBARITEMS];
- int NumMenus;
- string MenubarText;
- int CurrMenuItem;
-
- int OriginalFileBufID;
-
-
- /*
- Init() - initialization function - done once when the macro is loaded
- */
- init()
- {
- /* Set up the values for box-drawing characters */
- BoxChars[HORIZ] = "═";
- BoxChars[VERT] = "║";
- BoxChars[TOP_LEFT] = "╔";
- BoxChars[TOP_RIGHT] = "╗";
- BoxChars[BOT_LEFT] = "╚";
- BoxChars[BOT_RIGHT] = "╝";
-
- /* Set the dimensions of the menubar */
- MenuRow1 = 1;
- MenuCol1 = 0;
- MenuRow2 = 3;
- MenuCol2 = 79;
-
- /* CTRL-B will invoke the default menubar macro */
- assign_key("do_default_menu", 2);
- }
-
- do_default_menu()
- {
- do_menu("menubar");
- }
-
-
- /*
- Do_Menu() - driver for reading, parsing, and displaying a menubar. The
- passed argument is the root part of the menubar file name.
- */
- do_menu(menuname)
- string menuname;
- {
- debug = 0;
- menubar_already_here = 0;
-
- OriginalFileBufID = old_buf = currbuf();
-
- /* Open the Menubar definition file if it doesn't exist already. */
- if (!index(menuname, ".mnu"))
- menuname = strcat(menuname, ".mnu");
-
- if ((MenubarBuf = find_buffer(menuname)) <= 0)
- MenubarBuf = create_buffer(menuname);
- else
- menubar_already_here = 1;
- new_buf = setcurrbuf(MenubarBuf);
- setcol(1);
- vidsetcursor(32, 0);
-
- /* Parse the defn. If there's an error, abort. */
- if (!menubar_already_here)
- {
- if (MenuParse() < 0)
- {
- delete_buffer(new_buf);
- show_buffer(old_buf);
- return;
- }
- }
-
- /* Create a window for the menubar and attach the menubar buffer to it. */
- /* This is the ME paradigm for creating popup windows. */
- MenubarWindow = create_window(MenuRow1+1,MenuCol1+1,MenuRow2-1,MenuCol2-1,MenuColor);
- attach_window(MenubarWindow, new_buf);
- gobof();
- DrawBox(0, 0, 2, 79, MenuColor);
-
- /* Everything is displayed --- get the user input */
- MenubarProcess();
-
- /* After we're done, get rid of the menubar's window, */
- /* and go back to the file we were editing. */
- remove_window(MenubarWindow);
- show_buffer(old_buf);
- refresh();
- }
-
-
- /*
- MenuParse() - parse the menubar defn which is in the menubar buffer.
- Returns 1 if everything went OK, -1 if there was an error.
- */
- MenuParse()
- {
- int old_buf, new_buf;
-
- /* Span all initial comment lines */
- while (index(currline(), "MENUBAR") != 1)
- if (!down())
- return -1;
-
- /* The first token should be the word "MENUBAR" */
- if (get_token() != "MENUBAR")
- {
- get_tty_str("The file is not a menubar definition file");
- return -1;
- }
-
- /* The next token is the name of the menubar */
- MenuName = get_token();
-
- /*
- The cursor is either at the COLOR or the name of the first item
- */
- if ((s = get_token()) == "COLOR")
- MenuColor = get_int_token();
- else
- MenuColor = 07;
-
- old_buf = currbuf();
- NumMenus = 1;
-
- while (1)
- {
- /* The token should be the name of the popup */
- go_past_func = index(currline(), "->");
-
- if ((mname = get_token()) == "" || mname == "}")
- break;
- /* After this, the token ptr should be at the first item of the popup */
- MenuNames[NumMenus] = mname;
-
- if (go_past_func)
- {
- down();
- gobol();
- }
-
- if (index(currline(), "MENU") > 0)
- {
- MenuBuf[NumMenus] = new_buf = create_buffer(strcat(mname, ".men"));
- down();
- if (index(ltrim(currline()), "{"))
- {
- down();
- gobol();
- }
- }
- else
- MenuBuf[NumMenus] = new_buf = 0;
- NumMenus++;
-
- if (debug)
- get_tty_str("The name of the popup is [%s]", mname);
-
- itemcnt = 1;
-
- if (new_buf) /* We have a submenu */
- {
- /* Get each line until we encounter a line with a right curly brace. */
- /* Insert the entire line into the buffer which holds the submenu. */
- while (index(cl = ltrim(currline()), "}") == 0)
- {
- if (debug)
- get_tty_str("Inserting item [%s]", cl);
- oldcol = currcol();
- setcurrbuf(new_buf);
- if (itemcnt > 1)
- {
- goeol();
- insert("\n");
- }
- gobol();
- insert(ltrim(cl));
- itemcnt++;
-
- setcurrbuf(old_buf);
- setcol(oldcol);
- if (!down())
- break;
- gobol();
- } /* end while */
-
- /* Move to the next line after the right curly brace */
- if (!down() || currline() == "")
- break;
- gobol();
- } /* end if submenu */
- } /* end while */
-
- /* We form the menubar's text line by concatinating the menubar items. */
- /* We then stick this line on top of the menubar buffer. Since the */
- /* menubar window only shows 1 line, this is the line that we'll see. */
- MenubarText = MenuNames[1];
- for (i = 2; i <= NumMenus; i++)
- MenubarText = sprintf("%s %s", MenubarText, MenuNames[i]);
- gobof();
- insert(MenubarText); insert("\n");
- gobol();
-
- /* Success!!! */
- return 1;
- }
-
-
- get_token()
- {
- string s;
-
- if (is_eol() || currchar() == ' ')
- if (!nextword())
- return "";
-
- if (is_eof())
- return "";
-
- start = currcol();
- while (!is_eol() && currchar() != ' ')
- right();
- s = substr(currline(), start, currcol() - start);
- nextword();
- if (debug)
- get_tty_str(sprintf("GET_TOKEN returns [%s]", s));
- return s;
- }
-
- get_int_token()
- {
- n = atoi(get_token());
- if (debug)
- get_tty_str(sprintf("GET_INT_TOKEN - n is %d", n));
- return n;
- }
-
- /* ------------------------- MENU PROCESSING ------------------------- */
-
- #define ESC 27
- #define UP 200
- #define DOWN 208
-
- MenubarProcess()
- {
- CurrMenuItem = 1;
-
- do_it:
- highlite_word(1);
- if (MenuBuf[CurrMenuItem])
- {
- DrawPopup(currcol());
- c = MenuProcess();
- clear_mark();
- if (PopupWindow[CurrMenuItem])
- remove_window(PopupWindow[CurrMenuItem]);
- if (c == '\r' || c == ESC)
- return;
- show_buffer(setcurrbuf(MenubarBuf));
- DrawBox(0, 0, 2, 79, MenuColor);
- }
- else
- c = get_tty_char();
-
- if (c != '\r' && c != ESC)
- {
- switch (c)
- {
- case LEFT :
- MenuLeft();
- break;
- case RIGHT :
- MenuRight();
- break;
- default :
- bell();
- break;
- }
- }
- goto do_it;
- }
-
-
- MenuProcess()
- {
- markline();
-
- do_it:
- while ((c = get_tty_char()) != '\r' && c != ESC)
- {
- switch (c)
- {
- case UP :
- MenuUp();
- break;
- case DOWN :
- MenuDown();
- break;
- case LEFT :
- return(LEFT);
- case RIGHT :
- return(RIGHT);
- default :
- bell();
- break;
- }
- }
-
- if (c == '\r')
- {
- cln = currlinenum();
-
- if ((i = index(currline(), "->")) > 0)
- {
- macname = substr(currline(), i+2, 100);
- /*
- If we want to perform the macro on the original file we
- were editing, then we must switch back to the old buffer.
- */
- menubuf = currbuf();
- show_buffer(OriginalFileBufID);
- setprompt(2);
- domacro(macname);
- setprompt(0);
- setcurrbuf(menubuf);
- }
-
- if (debug)
- get_tty_str("After indirect call - before DrawBox");
- DrawBox(MenuRow1-1, MenuCol1, MenuRow2-1, MenuCol2, MenuColor);
- /*
- goto do_it;
- */
- }
-
- return c;
- }
-
-
-
- /*
- DrawPopup() - displays a submenu
- */
- DrawPopup(startcol)
- {
- /*
- BUGS - figure out how wide the submenu should be
- */
- setcurrbuf(MenuBuf[CurrMenuItem]);
- x1 = startcol - 1;
- x2 = x1 + 16;
- wid = create_window(4, x1+1, lastlinenum()+3, x2-1, 7);
- attach_window(wid, MenuBuf[CurrMenuItem]);
- PopupWindow[CurrMenuItem] = wid;
- gobof();
- DrawBox(2, x1, lastlinenum()+3, x2, MenuColor);
- }
-
- /*
- HighliteWord() - draws the current word with highliting (if rev is 1)
- */
- highlite_word(rev)
- {
- /* Determine the proper attribute to draw the word with */
- if (rev)
- rev = (MenuColor % 16) * 16 + (MenuColor / 16);
- else
- rev = MenuColor;
-
- /* Get the starting & ending columns of the word */
- col = currcol();
- endpos = index(substr(currline(), col, 100), " ") + col - 1;
- word = substr(currline(), col, endpos - col);
-
- /* Redraw the word with the specified attribute */
- display(1, col, endpos-1, rev, word);
- }
-
-
- /*
- MenuLeft() - move left one item in the menubar
- */
- MenuLeft()
- {
- highlite_word(0);
- if (!is_bol())
- CurrMenuItem--;
- prevword();
- highlite_word(1);
- }
-
- /*
- MenuRight() - move right one item in the menubar
- */
- MenuRight()
- {
- if (index(substr(currline(), currcol(), 100), " ") > 0)
- {
- highlite_word(0); /* remove highliting */
- if (!is_eol())
- CurrMenuItem++;
- nextword(); /* move to the next item */
- highlite_word(1); /* highlite the new item */
- }
- }
-
- /*
- MenuUp() - move up one line in the submenu
- */
- MenuUp()
- {
- if (currlinenum() > 1)
- {
- clear_mark(); /* remove highlite from the old line */
- up();
- markline(); /* highlight the new line */
- }
- }
-
- /*
- MenuDown() - move down one line in the submenu
- */
- MenuDown()
- {
- if (currlinenum() < lastlinenum())
- {
- clear_mark(); /* remove highlite from the old line */
- down();
- markline(); /* highlight the new line */
- }
- }
-
-
- /*
- DrawBox() - draws a box using the passed coordinates and attribute.
- */
- DrawBox(row1, col1, row2, col2, color)
- {
- width = col2 - col1 + 1;
- horiz_line = repstr(BoxChars[HORIZ], width - 2);
- blank_line = repstr(" ", width - 2);
-
- display(row1, col1 + 1, col1 + width - 1, color, horiz_line);
- display(row2, col1 + 1, col1 + width - 1, color, horiz_line);
- for (r = row1+1; r < row2; r++)
- {
- display(r, col1, col1, color, BoxChars[VERT]);
- display(r, col2, col2, color, BoxChars[VERT]);
- }
- display(row1, col1, col1, color, BoxChars[TOP_LEFT]);
- display(row1, col2, col2, color, BoxChars[TOP_RIGHT]);
- display(row2, col1, col1, color, BoxChars[BOT_LEFT]);
- display(row2, col2, col2, color, BoxChars[BOT_RIGHT]);
- }
-
-